<!DOCTYPE html>
<html>
<head>
<title>02第2章  初识Node.js.MD</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">

<style>
/* https://github.com/microsoft/vscode/blob/master/extensions/markdown-language-features/media/markdown.css */
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

body {
	font-family: var(--vscode-markdown-font-family, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif);
	font-size: var(--vscode-markdown-font-size, 14px);
	padding: 0 26px;
	line-height: var(--vscode-markdown-line-height, 22px);
	word-wrap: break-word;
}

#code-csp-warning {
	position: fixed;
	top: 0;
	right: 0;
	color: white;
	margin: 16px;
	text-align: center;
	font-size: 12px;
	font-family: sans-serif;
	background-color:#444444;
	cursor: pointer;
	padding: 6px;
	box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}

#code-csp-warning:hover {
	text-decoration: none;
	background-color:#007acc;
	box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}

body.scrollBeyondLastLine {
	margin-bottom: calc(100vh - 22px);
}

body.showEditorSelection .code-line {
	position: relative;
}

body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
	content: "";
	display: block;
	position: absolute;
	top: 0;
	left: -12px;
	height: 100%;
}

body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
	left: -30px;
}

.vscode-light.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(0, 0, 0, 0.15);
}

.vscode-light.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(0, 0, 0, 0.40);
}

.vscode-light.showEditorSelection .code-line .code-line:hover:before {
	border-left: none;
}

.vscode-dark.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 255, 255, 0.4);
}

.vscode-dark.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 255, 255, 0.60);
}

.vscode-dark.showEditorSelection .code-line .code-line:hover:before {
	border-left: none;
}

.vscode-high-contrast.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 160, 0, 0.7);
}

.vscode-high-contrast.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 160, 0, 1);
}

.vscode-high-contrast.showEditorSelection .code-line .code-line:hover:before {
	border-left: none;
}

img {
	max-width: 100%;
	max-height: 100%;
}

a {
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

a:focus,
input:focus,
select:focus,
textarea:focus {
	outline: 1px solid -webkit-focus-ring-color;
	outline-offset: -1px;
}

hr {
	border: 0;
	height: 2px;
	border-bottom: 2px solid;
}

h1 {
	padding-bottom: 0.3em;
	line-height: 1.2;
	border-bottom-width: 1px;
	border-bottom-style: solid;
}

h1, h2, h3 {
	font-weight: normal;
}

table {
	border-collapse: collapse;
}

table > thead > tr > th {
	text-align: left;
	border-bottom: 1px solid;
}

table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
	padding: 5px 10px;
}

table > tbody > tr + tr > td {
	border-top: 1px solid;
}

blockquote {
	margin: 0 7px 0 5px;
	padding: 0 16px 0 10px;
	border-left-width: 5px;
	border-left-style: solid;
}

code {
	font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
	font-size: 1em;
	line-height: 1.357em;
}

body.wordWrap pre {
	white-space: pre-wrap;
}

pre:not(.hljs),
pre.hljs code > div {
	padding: 16px;
	border-radius: 3px;
	overflow: auto;
}

pre code {
	color: var(--vscode-editor-foreground);
	tab-size: 4;
}

/** Theming */

.vscode-light pre {
	background-color: rgba(220, 220, 220, 0.4);
}

.vscode-dark pre {
	background-color: rgba(10, 10, 10, 0.4);
}

.vscode-high-contrast pre {
	background-color: rgb(0, 0, 0);
}

.vscode-high-contrast h1 {
	border-color: rgb(0, 0, 0);
}

.vscode-light table > thead > tr > th {
	border-color: rgba(0, 0, 0, 0.69);
}

.vscode-dark table > thead > tr > th {
	border-color: rgba(255, 255, 255, 0.69);
}

.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
	border-color: rgba(0, 0, 0, 0.18);
}

.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
	border-color: rgba(255, 255, 255, 0.18);
}

</style>

<style>
/* Tomorrow Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */

/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
	color: #8e908c;
}

/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
	color: #c82829;
}

/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
	color: #f5871f;
}

/* Tomorrow Yellow */
.hljs-attribute {
	color: #eab700;
}

/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
	color: #718c00;
}

/* Tomorrow Blue */
.hljs-title,
.hljs-section {
	color: #4271ae;
}

/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
	color: #8959a8;
}

.hljs {
	display: block;
	overflow-x: auto;
	color: #4d4d4c;
	padding: 0.5em;
}

.hljs-emphasis {
	font-style: italic;
}

.hljs-strong {
	font-weight: bold;
}
</style>

<style>
/*
 * Markdown PDF CSS
 */

 body {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "Meiryo";
	padding: 0 12px;
}

pre {
	background-color: #f8f8f8;
	border: 1px solid #cccccc;
	border-radius: 3px;
	overflow-x: auto;
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

pre:not(.hljs) {
	padding: 23px;
	line-height: 19px;
}

blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.emoji {
	height: 1.4em;
}

code {
	font-size: 14px;
	line-height: 19px;
}

/* for inline code */
:not(pre):not(.hljs) > code {
	color: #C9AE75; /* Change the old color so it seems less like an error */
	font-size: inherit;
}

/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
	page-break-after: always;
}

</style>

<script src="https://unpkg.com/mermaid/dist/mermaid.min.js"></script>
</head>
<body>
  <script>
    mermaid.initialize({
      startOnLoad: true,
      theme: document.body.classList.contains('vscode-dark') || document.body.classList.contains('vscode-high-contrast')
          ? 'dark'
          : 'default'
    });
  </script>
<h1 id="%E7%AC%AC2%E7%AB%A0-%E5%88%9D%E8%AF%86nodejs">第2章  初识Node.js</h1>
<ul>
<li><input type="checkbox" id="checkbox0"><label for="checkbox0"></label><strong>学习目标</strong></li>
</ul>
<ol>
<li>了解什么是客户端和服务端</li>
<li>了解什么是Node.js</li>
<li>掌握Node.js的安装与配置</li>
<li>掌握Node.js入门必备知识</li>
</ol>
<h2 id="nodejs%E6%A6%82%E8%BF%B0">Node.js概述</h2>
<p>​	随着互联网的发展，全栈工程师（Full Stack Engineer）的概念开始兴起，全栈即包括用户界面、业务逻辑、数据建模、服务器、网络及环境等。这意味着，全栈工程师要熟练处理各层间的交互。而现在，有了Nodejs的出现，用JavaScript语言既可以进行客户端开发，又可以进行服务器端的开发，还可以与数据库交互。</p>
<p>​	Stack Overflow 发布2020开发者报告（https://insights.stackoverflow.com/survey/2020#developer-profile-developer-type-all-respondents）显示，全栈工程师比例很高。</p>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/stack overflow&#x5BF9;&#x5F00;&#x53D1;&#x8005;&#x8C03;&#x67E5;.PNG" alt="stack overflow&#x5BF9;&#x5F00;&#x53D1;&#x8005;&#x8C03;&#x67E5;" style="zoom:50%;">
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/stack overflow&#x7F8E;&#x56FD;&#x5F00;&#x53D1;&#x8005;&#x8C03;&#x67E5;.PNG" alt="stack overflow&#x7F8E;&#x56FD;&#x5F00;&#x53D1;&#x8005;&#x8C03;&#x67E5;" style="zoom:50%;">
<h2 id="%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%92%8C%E6%9C%8D%E5%8A%A1%E7%AB%AF">客户端和服务端</h2>
<h3 id="%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%B8%8E%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%BC%A0%E7%BB%9F">客户端与服务端（传统）</h3>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x5BA2;&#x6237;&#x7AEF;&#x4E0E;&#x670D;&#x52A1;&#x7AEF;&#x4EA4;&#x4E92;.PNG" alt="&#x5BA2;&#x6237;&#x7AEF;&#x4E0E;&#x670D;&#x52A1;&#x7AEF;&#x4EA4;&#x4E92;" style="zoom:50%;">
<h3 id="%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%B8%8E%E6%9C%8D%E5%8A%A1%E7%AB%AFnode">客户端与服务端（Node）</h3>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/Node&#x51FA;&#x73B0;&#x540E;&#x7684;&#x5BA2;&#x6237;&#x7AEF;&#x4E0E;&#x670D;&#x52A1;&#x7AEF;.PNG" alt="Node&#x51FA;&#x73B0;&#x540E;&#x7684;&#x5BA2;&#x6237;&#x7AEF;&#x4E0E;&#x670D;&#x52A1;&#x7AEF;" style="zoom:50%;">
<h3 id="%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%B8%8E%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%BA%A4%E4%BA%92">客户端与服务端交互</h3>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x5BA2;&#x6237;&#x7AEF;&#x4E0E;&#x670D;&#x52A1;&#x7AEF;&#x4EA4;&#x4E92;-1599963001835.PNG" alt="&#x5BA2;&#x6237;&#x7AEF;&#x4E0E;&#x670D;&#x52A1;&#x7AEF;&#x4EA4;&#x4E92;" style="zoom:50%;">
<ol>
<li>
<p>请求报文：</p>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x8BF7;&#x6C42;&#x62A5;&#x6587;.jpg" alt="&#x8BF7;&#x6C42;&#x62A5;&#x6587;" style="zoom:50%;">
</li>
<li>
<p>响应报文</p>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x54CD;&#x5E94;&#x62A5;&#x6587;.jpg" alt="&#x54CD;&#x5E94;&#x62A5;&#x6587;" style="zoom:50%;">
<p>响应行：
①报文协议及版本；
②状态码及状态描述；
响应头：
③响应报文头，也是由多个属性组成；
响应体：
④响应报文体，即我们需要的信息内容</p>
<p>HTTP状态码共分为5种类型：</p>
<p>1** ：信息，服务器收到请求，需要请求者继续执行操作
2** ：成功，操作被成功接收并处理
3** ：重定向，需要进一步的操作以完成请求
4** ：客户端错误，请求包含语法错误或无法完成请求
5** ：服务器错误，服务器在处理请求的过程中发生了错误</p>
<p>常见HTTP状态码 :</p>
<p>1xx ：
100 Continue
继续。客户端应继续其请求</p>
<p>2xx ：
200 OK
请求已成功，请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。</p>
<p>204 No Content（无内容）
服务器成功处理，但未返回内容。在未更新网页的情况下，可确保浏览器继续显示当前文档。</p>
<p>206 Partial Content（部分内容）
服务器成功处理了部分GET请求。</p>
<p>3xx：
301 Moved Permanently（永久重定向）
请求的资源已被永久的移动到新URL，返回信息会包括新的URL，浏览器会自动定向到新URL。今后任何新的请求都应使用新的URI代替。</p>
<p>302 Found（临时重定向）
与301类似。但资源只是临时被移动。表示请求的资源被分配了新的URL，希望本次访问使用新的URL。</p>
<p>303 See Othe（查看其他地址）
当请求者应对不同的位置进行单独的 GET 请求以检索响应时，服务器会返回此代码。对于除 HEAD 请求之外的所有请求，服务器会自动转到其他位置。</p>
<p>304 Not Modified（未修改）
所请求的资源未修改，服务器返回此状态码时，不会返回任何资源。客户端通常会缓存访问过的资源，通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源。</p>
<p>305 Use Proxy（使用代理）
请求者只能使用代理访问请求的网页。如果服务器返回此响应，那么，服务器还会指明请求者应当使用的代理</p>
<p>307 Temporary Redire（临时重定向）
与303有着相同的含义，307会遵照浏览器标准不会从POST变成GET；（不同浏览器可能会出现不同的情况）。</p>
<p>4xx ：
400 Bad Request （语法错误）
客户端请求的语法错误，服务器无法理解。</p>
<p>401 Unauthorized（未授权）
请求要求用户的身份认证</p>
<p>403 Forbidden（禁止）
服务器理解请求客户端的请求，但是拒绝执行此请求</p>
<p>404 Not Found（未找到）
服务器无法根据客户端的请求找到资源（网页）。除此之外，也可以在服务器拒绝请求但不想给拒绝原因时使用。</p>
<p>405 Method Not Allowed （方法禁用）
客户端请求中的方法被禁止。</p>
<p>406 Not Acceptable（不接受）
无法使用请求的内容特性来响应请求的网页。</p>
<p>408 Request Time-out（请求超时）
服务器等待客户端发送的请求时间过长，超时。</p>
<p>5xx
500Internal Server Error（服务器内部错误）
服务器遇到错误，无法完成请求。</p>
<p>501 Not Implemented（尚未实施）
服务器不具备完成请求的功能。例如，当服务器无法识别请求方法时，服务器可能会返回此代码。</p>
<p>502 Bad Gateway（错误网关）
作为网关或者代理工作的服务器尝试执行请求时，从远程服务器接收到了一个无效的响应</p>
<p>503 Service Unavailable（服务不可用）
由于超载或系统维护，服务器暂时的无法处理客户端的请求。通常，这只是一种暂时的状态。</p>
<p>504 Gateway Time-out（网关超时）
服务器作为网关或代理，未及时从上游服务器接收请求。</p>
<p>505 HTTP Version not supported（HTTP 版本不受支持）
服务器不支持请求中所使用的 HTTP 协议版本。</p>
</li>
</ol>
<h3 id="javascript%E5%9C%A8%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%B8%8E%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%9A%84%E5%8C%BA%E5%88%AB">JavaScript在客户端与服务端的区别</h3>
<ol>
<li>JavaScript是脚本语言，一般运行在客户端，而Node.js可使JavaScript运行在服务器端。</li>
<li>JavaScript包括：ECMAScript、DOM和BOM3个部分：
<ol>
<li>ECMAScript：js核心语法</li>
<li>DOM：文档对象模型。如：ob1.style.color=&quot;red&quot;;</li>
<li>BOM：浏览器对象模型。如document.body.clientWidth</li>
</ol>
</li>
<li>客户端的JavaScirpt不仅应用核心语法ECMAScript，还会操作DOM和BOM，常见的应用场景如用户交互、动画特效、表单验证、发送Ajax请求等。</li>
<li>服务端的JavaScript应用核心语法ECMAScript，但是不操作DOM和BOM。它常常用来做一些在客户端做不到的事情，例如操作数据库、操作文件等，另外，在客户端的Ajax操作只能发送请求，而接受请求和做出响应的操作就需要服务端的JavaScript来完成。</li>
</ol>
<h2 id="nodejs%E7%9A%84%E5%AE%89%E8%A3%85%E5%92%8C%E9%85%8D%E7%BD%AE">Node.js的安装和配置</h2>
<h3 id="%E4%B8%8B%E8%BD%BD%E4%B8%8E%E5%AE%89%E8%A3%85">下载与安装</h3>
<ol>
<li>
<p>https://nodejs.org/zh-cn/</p>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/Node.js&#x4E0B;&#x8F7D;&#x4E0E;&#x5B89;&#x88C5;.PNG" alt="Node.js&#x4E0B;&#x8F7D;&#x4E0E;&#x5B89;&#x88C5;" style="zoom: 33%;">
</li>
<li>
<p>https://nodejs.org/zh-cn/download/</p>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/Node.js&#x4E0B;&#x8F7D;&#x4E0E;&#x5B89;&#x88C5;2.PNG" alt="Node.js&#x4E0B;&#x8F7D;&#x4E0E;&#x5B89;&#x88C5;2" style="zoom:33%;">
</li>
<li>
<p>安装后查看Node.js和NPM版本</p>
<p>node -v</p>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x67E5;&#x770B;node&#x7248;&#x672C;.PNG" alt="&#x67E5;&#x770B;node&#x7248;&#x672C;" style="zoom:50%;">
<p>npm -v</p>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x67E5;&#x770B;&#x5305;&#x7BA1;&#x7406;&#x5DE5;&#x5177;&#x7248;&#x672C;.PNG" alt="&#x67E5;&#x770B;&#x5305;&#x7BA1;&#x7406;&#x5DE5;&#x5177;&#x7248;&#x672C;" style="zoom:50%;">
<p>node.js安装后，要知道node.js安装在何处，命令窗口中是否可以执行node命令。如果不能执行node命令，则需要在“环境变量”中设置搜索路径Path。</p>
</li>
<li>
<p>命令窗口几个常用命令的使用</p>
<ul>
<li>dir 查看当前目录下所有条目</li>
<li>cd 切换目录</li>
<li>cls 清屏</li>
</ul>
</li>
</ol>
<h3 id="%E5%BF%AB%E9%80%9F%E4%BD%93%E9%AA%8Cnodejs">快速体验Node.js</h3>
<ol>
<li>
<p>在终端显示&quot;Hello world!&quot;</p>
<p>新建hello.js文件，文件代码如下，在代码文件所在目录下，使用node .\hello.js命令运行。</p>
<pre class="hljs"><code><div><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello world!"</span>);
</div></code></pre>
<p>运行结果如下图所示。</p>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x8FD0;&#x884C;&#x7ED3;&#x679C;1.PNG" alt="&#x8FD0;&#x884C;&#x7ED3;&#x679C;1" style="zoom:50%;">
</li>
<li>
<p>创建一个Web服务器，监听IP地址为127.0.0.1，端口为3000的访问请求，向该访问请求的页面中输出“Hello world”。</p>
<ol>
<li>新建demo2-2.js；</li>
<li>代码如下所示；</li>
</ol>
<pre class="hljs"><code><div><span class="hljs-comment">// 加载http模块</span>
<span class="hljs-keyword">var</span> http=<span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
<span class="hljs-comment">// 创建http服务器</span>
http.createServer(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">req, res</span>)</span>{
    <span class="hljs-comment">// 响应结束</span>
    res.end(<span class="hljs-string">'Hello world'</span>)
}).listen(<span class="hljs-number">3000</span>,<span class="hljs-string">'127.0.0.1'</span>);<span class="hljs-comment">//监听网址与端口</span>
</div></code></pre>
<ol start="3">
<li>在代码文件所在目录下，运行代码文件；</li>
</ol>
<pre class="hljs"><code><div>node .\demo2<span class="hljs-number">-2.</span>js
</div></code></pre>
<ol start="4">
<li>运行结果如下图所示。</li>
</ol>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x8FD0;&#x884C;&#x7ED3;&#x679C;2.PNG" alt="&#x8FD0;&#x884C;&#x7ED3;&#x679C;2" style="zoom:50%;">
<ol start="5">
<li>本示例代码可稍加改进，如下所示。</li>
</ol>
<pre class="hljs"><code><div><span class="hljs-comment">// 加载http模块</span>
<span class="hljs-keyword">var</span> http=<span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
<span class="hljs-comment">// 创建http服务器</span>
<span class="hljs-keyword">var</span> server=http.createServer();
<span class="hljs-comment">// 监听request事件</span>
server.on(<span class="hljs-string">'request'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">req, res</span>)</span>{
    <span class="hljs-keyword">var</span> url=req.url;<span class="hljs-comment">//不包括IP与端口部分</span>
    <span class="hljs-keyword">if</span>(url===<span class="hljs-string">'/'</span>){
        res.end(<span class="hljs-string">"Hello world!!"</span>);
    }<span class="hljs-keyword">else</span>{
        res.end(<span class="hljs-string">'404 Not Found'</span>);
    }
});
server.listen(<span class="hljs-number">3000</span>,()=&gt;{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'server is listening at port 3000'</span>);
})
</div></code></pre>
</li>
</ol>
<h3 id="%E5%85%A8%E5%B1%80%E5%8F%AF%E7%94%A8%E5%8F%98%E9%87%8F%E5%87%BD%E6%95%B0%E5%92%8C%E5%AF%B9%E8%B1%A1">全局可用变量、函数和对象</h3>
<ol>
<li>
<p>理解全局作用域</p>
<p>全局作用域含义是在Node.js环境中，不需要加载任何模块，直接可以使用。Node.js中有全局变量、全局函数、全局对象。</p>
</li>
<li>
<p>全局对象</p>
<ul>
<li>
<p>global：表示Node所在的全局环境，类似于浏览器的window对象。任何全局属性、方法都是这个global对象的成员。</p>
</li>
<li>
<p>process：该对象表示Node所处的当前进程，允许开发者与该进程互动。</p>
</li>
<li>
<p>console：指向Node内置的console模块，提供命令行环境中的标准输入、标准输出功能。</p>
</li>
</ul>
<p>可以通过代码查看global对象的成员。</p>
<pre class="hljs"><code><div><span class="hljs-built_in">console</span>.log(global)
<span class="hljs-built_in">console</span>.log(global.console)
</div></code></pre>
</li>
<li>
<p>全局函数</p>
<ul>
<li>setTimeout()：用于在指定毫秒之后，运行回调函数。实际的调用间隔，还取决于系统因素。间隔的毫秒数在1毫秒到2,147,483,647毫秒（约24.8天）之间。如果超过这个范围，会被自动改为1毫秒。该方法返回一个整数，代表这个新建定时器的编号。</li>
<li>clearTimeout()：用于终止一个setTimeout方法新建的定时器。</li>
<li>setInterval()：用于每隔一定毫秒调用回调函数。由于系统因素，可能无法保证每次调用之间正好间隔指定的毫秒数，但只会多于这个间隔，而不会少于它。指定的毫秒数必须是1到2,147,483,647（大约24.8天）之间的整数，如果超过这个范围，会被自动改为1毫秒。该方法返回一个整数，代表这个新建定时器的编号。</li>
<li>clearInterval()：终止一个用setInterval方法新建的定时器。</li>
<li>require()：用于加载模块。</li>
</ul>
<pre class="hljs"><code><div><span class="hljs-comment">// settimeout.js</span>
setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    <span class="hljs-comment">// 2 秒之后运行</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"2秒后。。。"</span>)
}, <span class="hljs-number">2000</span>)

<span class="hljs-keyword">const</span> id = setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    <span class="hljs-comment">// 应该在 3 秒之后运行</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"3秒后。。。"</span>)
}, <span class="hljs-number">3000</span>)

setTimeout(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    <span class="hljs-comment">// 50 毫秒之后运行</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"50毫秒后。。。"</span>)<span class="hljs-comment">//先执行</span>
}, <span class="hljs-number">50</span>)

<span class="hljs-comment">// 改变主意了</span>
clearTimeout(id)
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// setinterval.js</span>
<span class="hljs-keyword">var</span> i=<span class="hljs-number">1</span>,s=<span class="hljs-number">0</span>;
<span class="hljs-keyword">const</span> interval = setInterval(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    <span class="hljs-keyword">if</span> (i === <span class="hljs-number">11</span>) {
        clearInterval(interval)
        <span class="hljs-keyword">return</span>
    }
    <span class="hljs-comment">// 否则做些事情</span>
    s+=i++;
    <span class="hljs-built_in">console</span>.log(s)    
}, <span class="hljs-number">400</span>)
</div></code></pre>
</li>
<li>
<p>两个全局变量</p>
<p>__filename：指向当前运行的脚本文件名。</p>
<p>__dirname：指向当前运行的脚本所在的目录。</p>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);  <span class="hljs-comment">// node内置模块。</span>
<span class="hljs-comment">// path.join() 拼接路径</span>
<span class="hljs-keyword">var</span> fullPath = path.join(__dirname, <span class="hljs-string">'mylog'</span>);
<span class="hljs-built_in">console</span>.log(fullPath); 
<span class="hljs-comment">// path.extname() 获取文件的后缀名</span>
<span class="hljs-keyword">var</span> extname = path.extname(__filename);
<span class="hljs-built_in">console</span>.log(extname);  <span class="hljs-comment">// .js</span>

<span class="hljs-comment">// path.basename() 截取路径中最后一个"/"后的内容 (可以截取出文件名)</span>
<span class="hljs-keyword">var</span> basename = path.basename(<span class="hljs-string">'c:/aa/bb/dd.html'</span>);  <span class="hljs-comment">// 截取路径中最后一个"/"后的内容</span>
<span class="hljs-built_in">console</span>.log(basename);   <span class="hljs-comment">// dd.html</span>
<span class="hljs-keyword">var</span> basename2 = path.basename(<span class="hljs-string">'c:/aa/bb/dd.html'</span>, <span class="hljs-string">'.html'</span>);
<span class="hljs-built_in">console</span>.log(basename2);   <span class="hljs-comment">// dd</span>

<span class="hljs-comment">// path.dirname() 截取路径名</span>
<span class="hljs-keyword">var</span> dirname = path.dirname(<span class="hljs-string">'c:/aa/bb/dd.html'</span>);
<span class="hljs-built_in">console</span>.log(dirname);   <span class="hljs-comment">// c:/aa/bb</span>
</div></code></pre>
</li>
</ol>
<h3 id="nodejs%E6%A8%A1%E5%9D%97%E5%8C%96%E9%87%8D%E5%86%99%E8%AE%A1%E7%AE%97%E5%99%A8%E6%A1%88%E4%BE%8B">Node.js模块化重写计算器案例</h3>
<pre class="hljs"><code><div><span class="hljs-comment">// add.js</span>
<span class="hljs-comment">// 加法</span>
<span class="hljs-built_in">module</span>.exports=<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x,y</span>)</span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseInt</span>(x)+<span class="hljs-built_in">parseInt</span>(y)
}
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// subtract.js</span>
<span class="hljs-comment">// 减法</span>
<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">x, y</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseInt</span>(x) - <span class="hljs-built_in">parseInt</span>(y)
}
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// multiply.js</span>
<span class="hljs-comment">// 乘法</span>
<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">x, y</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseInt</span>(x) * <span class="hljs-built_in">parseInt</span>(y)
}
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// divide.js</span>
<span class="hljs-comment">// 除法</span>
<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">x, y</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseInt</span>(x) / <span class="hljs-built_in">parseInt</span>(y)
}
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// index.js</span>
<span class="hljs-comment">// 入口模块</span>
<span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">add</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'./add.js'</span>),
    <span class="hljs-attr">sub</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'./subtract'</span>),
    <span class="hljs-attr">mul</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'./multiply'</span>),
    <span class="hljs-attr">div</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'./divide'</span>),
}
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// testCal.js</span>
<span class="hljs-comment">// 测试计算器</span>
<span class="hljs-keyword">var</span> cal = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./index'</span>)
<span class="hljs-built_in">console</span>.log(cal.add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
<span class="hljs-built_in">console</span>.log(cal.sub(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
<span class="hljs-built_in">console</span>.log(cal.mul(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
<span class="hljs-built_in">console</span>.log(cal.div(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
</div></code></pre>
<img src="file:///d:/&#x6559;&#x5B66;/20-21&#x7B2C;&#x4E00;&#x5B66;&#x671F;/Node.js&#x5165;&#x95E8;/&#x8BFE;&#x7A0B;&#x8FDB;&#x5EA6;/02/&#x7B2C;2&#x7AE0;/02&#x7B2C;2&#x7AE0;  &#x521D;&#x8BC6;Node.js.assets/&#x8FD0;&#x884C;&#x7ED3;&#x679C;3.PNG" alt="&#x8FD0;&#x884C;&#x7ED3;&#x679C;3" style="zoom:50%;">
<h3 id="%E5%B0%8F%E7%BB%93">小结</h3>
<p>​	客户端与服务端的基本概念和交互，Node.js的下载与安装，掌握全局对象、全局函数、全局变量，初步体验Node.js。</p>

</body>
</html>
